﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sgr.Data
{
    /// <summary>
    /// 默认的数据库种子实现类
    /// 负责按顺序执行所有实现了 IDataBaseInitialize 接口的数据库初始化任务
    /// </summary>
    public class DefaultDatabaseSeed : IDatabaseSeed
    {
        private readonly ILogger<DefaultDatabaseSeed> _logger;
        private readonly IEnumerable<IDataBaseInitialize> _initializes;

        private static readonly SemaphoreSlim _initLock = new(1, 1);

        /// <summary>
        /// 构造函数，注入日志记录器和所有数据库初始化任务
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="initializes">所有数据库初始化任务集合</param>
        public DefaultDatabaseSeed(ILogger<DefaultDatabaseSeed> logger, IEnumerable<IDataBaseInitialize> initializes)
        {
            _logger = logger;
            _initializes = initializes;
        }

        /// <summary>
        /// 执行数据库种子初始化
        /// </summary>
        public async Task SeedAsync()
        {
            // 如果没有任何数据库初始化任务，记录日志并返回
            if (!_initializes.Any())
            {
                _logger.LogInformation($"未设置任何数据库初始化任务！");
                return;
            }

            await _initLock.WaitAsync();
            try
            {
                // 按 Order 属性升序排列所有初始化任务
                List<IDataBaseInitialize> items = _initializes.OrderBy(f => f.Order).ToList();
                // 依次执行每个初始化任务
                foreach (IDataBaseInitialize item in items)
                {
                    await item.Initialize();

                    _logger.LogInformation($"第 [{item.Order.ToString("00000")}] 号 [ {item.GetType().Name} ] 初始化任务已完成 ............");
                }
                _logger.LogInformation($"数据库种子初始化完成！共执行 {items.Count} 个任务");
            }
            finally
            {
                _initLock.Release();
            }
        }
    }
}